package cn.hengzhu.main_manager.web.gzh;

import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;

import cn.hengzhu.main_manager.repository.dao.CaseAdvertiseFileMapper;
import cn.hengzhu.main_manager.repository.dao.CaseAdvertiseMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseBoxMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseMapper;
import cn.hengzhu.main_manager.repository.dao.ManagePermissionMapper;
import cn.hengzhu.main_manager.repository.dao.ManageRolesMapper;
import cn.hengzhu.main_manager.repository.dao.ManageUserMapper;
import cn.hengzhu.main_manager.repository.dao.SysConstMapper;
import cn.hengzhu.main_manager.repository.domain.CaseAdvertise;
import cn.hengzhu.main_manager.repository.domain.CaseAdvertiseExample;
import cn.hengzhu.main_manager.repository.domain.CaseAdvertiseFile;
import cn.hengzhu.main_manager.repository.domain.CaseAdvertiseFileExample;
import cn.hengzhu.main_manager.repository.domain.ManageCase;
import cn.hengzhu.main_manager.repository.domain.ManageCaseBox;
import cn.hengzhu.main_manager.repository.domain.ManageCaseBoxExample;
import cn.hengzhu.main_manager.repository.domain.ManageCaseExample;
import cn.hengzhu.main_manager.repository.domain.ManagePermission;
import cn.hengzhu.main_manager.repository.domain.ManagePermissionExample;
import cn.hengzhu.main_manager.repository.domain.ManageRoles;
import cn.hengzhu.main_manager.repository.domain.ManageUser;
import cn.hengzhu.main_manager.repository.domain.SysConst;
import cn.hengzhu.main_manager.repository.domain.SysConstExample;
import cn.hengzhu.main_manager.repository.vo.AdRenturnVO;
import cn.hengzhu.main_manager.repository.vo.OpenBoxListVO;
import cn.hengzhu.main_manager.service.ManageCaseBoxService;
import cn.hengzhu.main_manager.service.ManageCaseService;
import cn.hengzhu.main_manager.utils.AjaxResult;
import cn.hengzhu.main_manager.utils.DateTimeHelper;
import cn.hengzhu.main_manager.utils.DetailDate;
import cn.hengzhu.main_manager.utils.HttpClientUtil;
import cn.hengzhu.main_manager.utils.Md5Util;
import cn.hengzhu.main_manager.utils.MessageData;
import cn.hengzhu.main_manager.utils.MessageTemplate;
import cn.hengzhu.main_manager.utils.SecurityUtil;
import cn.hengzhu.main_manager.utils.ann.SystemControllerLog;
import cn.hengzhu.main_manager.utils.config.AliOssConfig;
import cn.hengzhu.main_manager.utils.config.gzh.WeiXinConst;

/**
 * @author YanFa001
 * 
 */
@Controller
@RequestMapping("/weixin/open")
public class WeixinAccessController {
	@Autowired
	private ManageCaseBoxService manageCaseBoxService;
	@Autowired
	private CaseAdvertiseMapper caseAdvertiseMapper;
	@Autowired
	private CaseAdvertiseFileMapper caseAdvertiseFileMapper;
	@Autowired
	private ManageCaseBoxMapper manageCaseBoxMapper;
	@Autowired
	private SysConstMapper sysConstMapper;
	@Autowired
	private ManageCaseMapper manageCaseMapper;
	@Autowired
	private ManageCaseService manageCaseService;
	@Autowired
	private ManageUserMapper manageUserMapper;
	@Autowired
	private ManageRolesMapper manageRolesMapper;
	@Autowired
	private ManagePermissionMapper managePermissionMapper;


	@RequestMapping("/openPage")
	public String getOpen(String caseNo, Model model, Long timestamp, String token, HttpServletRequest request)
			throws Exception {

		// 查询二维码过期时间
		Long overTime = 5l;
		SysConstExample example = new SysConstExample();
		example.createCriteria().andNameEqualTo("QR_CODE_OVERTIME"); // NAME =  QR_CODE_OVERTIME

		List<SysConst> sysConst = sysConstMapper.selectByExample(example);
		if (sysConst != null && !sysConst.isEmpty()) {
			String value = sysConst.get(0).getValue();
			overTime = Long.valueOf(value);
		}

		String sha1 = SecurityUtil.sha1(timestamp.toString());
		if (sha1.equals(token)) {
			Long time = new Date().getTime();
			Long min = (time - timestamp) / 60000;
			if (min < overTime) {
				model.addAttribute("caseNo", caseNo);
				return "open";
			} else {
				return "openOut";
			}
		} else {
			return "openerr";
		}

	}


	@RequestMapping("/opened")
	public String opened() throws Exception {
		return "opened";
	}

	@RequestMapping("/please")
	public String please() throws Exception {
		return "please";
	}

	@RequestMapping("/adminOpened")
	public String adminOpened() throws Exception {
		return "adminOpened";
	}

	/**
	 * @param caseNo
	 * @param request
	 * @param response
	 * @return 列表
	 */
	@SystemControllerLog(description = "微信获取储物柜列表")
	@ResponseBody
	@RequestMapping("/getBoxList")
	public OpenBoxListVO getBoxList(String caseNo, HttpServletRequest request, HttpServletResponse response) {
		String fromUserName = (String) request.getSession().getAttribute("fromUserName");
		OpenBoxListVO boxList = manageCaseBoxService.getBoxList(caseNo, fromUserName);
		return boxList;

	}

	/**
	 * @return 开箱操作
	 * @throws Exception
	 * @throws JMSException
	 */
	@SystemControllerLog(description = "微信开箱操作")
	@ResponseBody
	@RequestMapping("/openDoor")
	public Map<String, String> saveThing(String caseNo, Integer boxNum, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String fromUserName = (String) request.getSession().getAttribute("fromUserName");
		Map<String, String> map = manageCaseBoxService.getOpenDoor(fromUserName, caseNo, boxNum);
		return map;
	}

	/**
	 * @return 一键开箱操作
	 * @throws Exception
	 * @throws JMSException
	 */
	@SystemControllerLog(description = "微信一键开箱")
	@ResponseBody
	@RequestMapping("/oneKeyOpen")
	public Map<String, String> oneKeyOpen(String caseNo, Integer boxNum, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String fromUserName = (String) request.getSession().getAttribute("fromUserName");
		Map<String, String> map = manageCaseBoxService.oneKeyOpen(caseNo, fromUserName);
		return map;
	}

	/**
	 * 清除操作
	 * 
	 * @author 刘成
	 * @since 2018年7月7日
	 * @param caseNo
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@SystemControllerLog(description = "微信清除操作")
	@ResponseBody
	@RequestMapping("/clear")
	public AjaxResult clear(Integer boxNum, String caseNo, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ManageCaseBoxExample boxExample = new ManageCaseBoxExample();
		boxExample.createCriteria().andCaseNoEqualTo(caseNo).andDoorNumEqualTo(boxNum).andIsDelEqualTo((byte) 0);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(boxExample);
		if (!selectByExample.isEmpty()) {
			ManageCaseBox boxByBoxNum = selectByExample.get(0);
			Integer boxId = boxByBoxNum.getId();
			Byte useStatus = boxByBoxNum.getUseStatus();
			String fromUserName = (String) request.getSession().getAttribute("fromUserName");
			if (Byte.valueOf("1").equals(useStatus)) {
				try {
					manageCaseBoxService.boxClearByWX(boxId, fromUserName);

					// 清除成功后，发送微信消息
					manageCaseService.getToken();

					ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
					ManageCaseExample caseExample = new ManageCaseExample();
					caseExample.createCriteria().andCaseNoEqualTo(caseNo);
					List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(caseExample);
					MessageTemplate messageTemplate = new MessageTemplate();
					messageTemplate.setTouser(manageCaseBox.getUserId());
					MessageData data = new MessageData();
					DetailDate first = new DetailDate();// #8B2500
					first.setColor("#8B2500");
					first.setValue("您好，您使用储物柜因超时已被清理");
					data.setFirst(first);
					DetailDate keyword1 = new DetailDate();
					keyword1.setColor("#8B2500");
					if (!selectByExample2.isEmpty()) {
						ManageCase caseByCaseNo = selectByExample2.get(0);
						keyword1.setValue(caseByCaseNo.getPlace());
					}
					data.setKeyword1(keyword1);
					DetailDate keyword2 = new DetailDate();
					keyword2.setColor("#8B2500");
					keyword2.setValue(boxNum + "号门");
					data.setKeyword2(keyword2);
					DetailDate keyword3 = new DetailDate();
					keyword3.setColor("#8B2500");
					keyword3.setValue(
							DateTimeHelper.formatDateTimetoString(manageCaseBox.getSaveTime(), "yyyy-MM-dd HH:mm:ss"));
					data.setKeyword3(keyword3);
					DetailDate remar = new DetailDate();
					remar.setColor("#8B2500");
					remar.setValue("如有疑问，请尽快联系管理员,并取回自己的物品！！！");
					data.setRemark(remar);
					messageTemplate.setData(data);
					String jsonString = JSONObject.toJSONString(messageTemplate);

					SysConstExample example = new SysConstExample();
					example.createCriteria().andNameEqualTo("ACCESS_TOKEN");
					List<SysConst> sysConst = sysConstMapper.selectByExample(example);
					String accessToken = sysConst.get(0).getValue();
					String url = WeiXinConst.MESSAGE_TEMPLATE.replace("ACCESS_TOKEN", accessToken);
					HttpClientUtil.httpPost(url, jsonString);

					return new AjaxResult();
				} catch (Exception e) {
					e.printStackTrace();
					return new AjaxResult("清除失败");
				}
			} else {
				return new AjaxResult();
			}

		} else {
			return new AjaxResult("清除失败");
		}
	}

	/**
	 * @param caseNo
	 * @return
	 * @throws Exception 获取广告的地址，json
	 */
	@SystemControllerLog(description = "客户端获取广告地址")
	@ResponseBody
	@RequestMapping("/getAdvertisList")
	public Map<String, List<AdRenturnVO>> getAdvertisList(String caseNo) throws Exception {
		Map<String, List<AdRenturnVO>> map = new HashMap<String, List<AdRenturnVO>>();
		List<AdRenturnVO> list = new ArrayList<>();

		CaseAdvertiseExample example = new CaseAdvertiseExample();
		example.createCriteria().andIsDelEqualTo((byte) 0).andCaseNoEqualTo(caseNo);
		List<CaseAdvertise> caseAdvertiseList = caseAdvertiseMapper.selectByExample(example);

		if (!caseAdvertiseList.isEmpty()) {
			List<Integer> fileIdList = caseAdvertiseList.stream()
					.collect(Collectors.mapping(CaseAdvertise::getFileId, Collectors.toList())).stream().distinct()
					.collect(Collectors.toList());

			CaseAdvertiseFileExample fileExample = new CaseAdvertiseFileExample();
			fileExample.createCriteria().andFileIdIn(fileIdList);
			List<CaseAdvertiseFile> fileByList = caseAdvertiseFileMapper.selectByExample(fileExample);

			if (!fileByList.isEmpty()) {

				for (CaseAdvertiseFile caseAdvertiseFile : fileByList) {
					AdRenturnVO adRenturnVO = new AdRenturnVO();
					String url = AliOssConfig.URL + caseAdvertiseFile.getUrl();

					Integer height = caseAdvertiseFile.getHeight();
					Integer width = caseAdvertiseFile.getWidth();
					Byte type = caseAdvertiseFile.getType();// 0.图片 1.视频 2.音频
					if (Byte.valueOf("0").equals(type)) {
						if (null != height && null != width) {
							adRenturnVO.setHigh(height);
							adRenturnVO.setWidth(width);
						} else {
							InputStream murl = new URL(url).openStream();
							BufferedImage sourceImg = ImageIO.read(murl);
							int height2 = sourceImg.getHeight();
							int width2 = sourceImg.getWidth();
							adRenturnVO.setHigh(height2);
							adRenturnVO.setWidth(width2);
							caseAdvertiseFile.setWidth(width2);
							caseAdvertiseFile.setHeight(height2);
							murl.close();
							caseAdvertiseFileMapper.updateByPrimaryKeySelective(caseAdvertiseFile);
						}
					}
					adRenturnVO.setUrl(url);
					adRenturnVO.setFlag(type);
					list.add(adRenturnVO);
				}
			}

		}
		map.put("url", list);
		return map;
	}

	/**
	 * 对微信菜单里面"绑定用户"进行响应
	 */
	@RequestMapping("/binder")
	public String index(HttpServletRequest request, HttpServletResponse response) throws Exception {
		return "binder";
	}

	/**
	 * 当在绑定页面输入"用户名和密码后",点击绑定是会处理
	 */
	@SystemControllerLog(description = "用户账号绑定")
	@RequestMapping("/bindingResult")
	public ModelAndView binder(ManageUser manageUser, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		String fromUserName = (String) request.getSession().getAttribute("fromUserName");
		if (StringUtils.isNotBlank(fromUserName)) {
			String hash = Md5Util.hash(manageUser.getPassWord());

			ManageUser findByLoginNameAndPassWord = manageUserMapper
					.findByLoginNameAndPassWord(manageUser.getLoginName(), hash);
			// 绑定用户不存在,要跳转到绑定页面,并且给出错误提示信息
			if (findByLoginNameAndPassWord == null) {
				return new ModelAndView("binder", "msg", "用户名或密码不正确!");
			} else {
				Integer roleId = findByLoginNameAndPassWord.getRoleId();
				ManageRoles manageRoles = manageRolesMapper.selectByPrimaryKey(roleId);
				String permissions = manageRoles.getPermissions();
				List<String> permissionIds = Arrays.asList(permissions.split(","));

				List<Integer> codesInteger = permissionIds.stream().map(Integer::parseInt).collect(Collectors.toList());
				ManagePermissionExample permissionExample = new ManagePermissionExample();
				permissionExample.createCriteria().andIdIn(codesInteger);
				List<ManagePermission> permissionsByIds = managePermissionMapper.selectByExample(permissionExample);

				List<String> snList = permissionsByIds.stream()
						.collect(Collectors.mapping(ManagePermission::getSn, Collectors.toList()));
				boolean contains = snList.contains(WeiXinConst.PERMISSION_OPENBOX);
				if (contains) {
					try {
						findByLoginNameAndPassWord.setFormUserName(fromUserName);
						manageUserMapper.updateByPrimaryKeySelective(findByLoginNameAndPassWord);
						return new ModelAndView("binder", "msg", "绑定成功");
					} catch (Exception e) {
						return new ModelAndView("binder", "msg", "绑定失败，请重试");
					}
				} else {
					return new ModelAndView("binder", "msg", "没有开箱权限不能绑定");
				}
			}

		} else {
			return new ModelAndView("binder", "msg", "绑定失败");
		}
	}

}
